package org.dromara.hm.service.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.RequiredArgsConstructor;
import org.dromara.common.core.exception.ServiceException;
import org.dromara.common.core.service.DeptService;
import org.dromara.common.core.service.UserService;
import org.dromara.common.core.utils.MapstructUtils;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.json.utils.JsonUtils;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.satoken.utils.LoginHelper;
import org.dromara.hm.domain.HmIssueReceiptRecords;
import org.dromara.hm.domain.HmStock;
import org.dromara.hm.domain.HmTodoItems;
import org.dromara.hm.domain.bo.HmSaleOrderRefundBo;
import org.dromara.hm.domain.bo.HmStockChangeBo;
import org.dromara.hm.domain.bo.HmTodoItemsBo;
import org.dromara.hm.domain.vo.HmCustomerVo;
import org.dromara.hm.domain.vo.HmIssueReceiptRecordsVo;
import org.dromara.hm.domain.vo.saleOrder.HmSaleOrderRefundVo;
import org.dromara.hm.domain.vo.HmStockVo;
import org.dromara.hm.domain.vo.HmTodoItemsVo;
import org.dromara.hm.enums.ReceiptIssueRecordTypeEnum;
import org.dromara.hm.enums.StockChangeTypeEnum;
import org.dromara.hm.enums.ToDoTypeEnum;
import org.dromara.hm.enums.TodoFollowIpTypeEnum;
import org.dromara.hm.enums.TodoItemStatus;
import org.dromara.hm.mapper.HmCustomerMapper;
import org.dromara.hm.mapper.HmIssueReceiptRecordsMapper;
import org.dromara.hm.mapper.HmStockMapper;
import org.dromara.hm.mapper.HmTodoItemsMapper;
import org.dromara.hm.service.IHmSaleOrderRefundService;
import org.dromara.hm.service.IHmStockChangeService;
import org.dromara.hm.service.IHmTodoItemsService;
import org.dromara.hm.service.IHmPaymentAdjustmentService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Arrays;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

import static org.dromara.hm.enums.ReceiptIssueRecordTypeEnum.INBOUND;

/**
 * 代办事项Service业务层处理
 *
 * @author zy Hu
 * @date 2024-12-15
 */
@RequiredArgsConstructor
@Service
public class HmTodoItemsServiceImpl implements IHmTodoItemsService
{

    private final HmTodoItemsMapper baseMapper;

    /**
     * 出入库记录单
     */
    private final HmIssueReceiptRecordsMapper issueReceiptRecordsMapper;

    /**
     * 库存记录
     */
    private final HmStockMapper stockMapper;

    private final HmCustomerMapper customerService;

    private final IHmStockChangeService hmStockChangeService;

    private final DeptService deptService;

    private final IHmSaleOrderRefundService hmSaleOrderRefundService;

    private final UserService userService;


    /**
     * 查询代办事项
     *
     * @param todoId 主键
     *
     * @return 代办事项
     */
    @Override

    public HmTodoItemsVo queryById(Long todoId)
    {
        HmTodoItemsVo hmTodoItemsVo = baseMapper.selectVoById(todoId);
        // 处理空值和空字符串的情况
        String todoFileStr = hmTodoItemsVo.getTodoFile();
        if (StringUtils.isBlank(todoFileStr))
        {
            hmTodoItemsVo.setTodoFiles(List.of(new String[0]));
        }
        else
        {
            String[] todoFiles = todoFileStr.split(",");
            hmTodoItemsVo.setTodoFiles(Arrays.stream(todoFiles).toList());
        }
        // 根据出库单返回入库单的入库数量、入库商品、入库店铺
        if (hmTodoItemsVo.getTodoOutboundOrder() != null || hmTodoItemsVo.getTodoWarehouseReceipt() != null)
        {
            long requestId = hmTodoItemsVo.getTodoOutboundOrder() != null ? hmTodoItemsVo.getTodoOutboundOrder() : hmTodoItemsVo.getTodoWarehouseReceipt();
            HmIssueReceiptRecordsVo hmIssueReceiptRecordsVo = issueReceiptRecordsMapper.selectVoById(requestId);
            if (ObjectUtil.isNotNull(hmIssueReceiptRecordsVo))
            {
                // 操作数量
                hmTodoItemsVo.setTodoStockNum(hmIssueReceiptRecordsVo.getRecordNum());
                // 出库店铺
                hmTodoItemsVo.setTodoOutboundDept(Long.valueOf(hmIssueReceiptRecordsVo.getRecordStartLocation()));
                if (!ReceiptIssueRecordTypeEnum.EMPLOYEE_BENEFITS.getCode()
                    .equals(hmIssueReceiptRecordsVo.getRecordType()) && !ReceiptIssueRecordTypeEnum.CUSTOMER_GIFTS.getCode()
                    .equals(hmIssueReceiptRecordsVo.getRecordType()) && !ReceiptIssueRecordTypeEnum.FRINGE_MARKET.getCode()
                    .equals(hmIssueReceiptRecordsVo.getRecordType()))
                {
                    // 入库店铺
                    hmTodoItemsVo.setTodoStockDept(Long.valueOf(hmIssueReceiptRecordsVo.getRecordEndLocation()));
                }

                // 入库商品. 操作商品
                hmTodoItemsVo.setTodoStockGoodsId(hmIssueReceiptRecordsVo.getRecordProductId());
            }

        }
        return hmTodoItemsVo;
    }

    /**
     * 分页查询代办事项列表
     *
     * @param bo        查询条件
     * @param pageQuery 分页参数
     *
     * @return 代办事项分页列表
     */
    @Override
    public TableDataInfo<HmTodoItemsVo> queryPageList(HmTodoItemsBo bo, PageQuery pageQuery)
    {
        LambdaQueryWrapper<HmTodoItems> lqw = buildQueryWrapper(bo);
        Page<HmTodoItemsVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        return TableDataInfo.build(result);
    }

    /**
     * 查询符合条件的代办事项列表
     *
     * @param bo 查询条件
     *
     * @return 代办事项列表
     */
    @Override
    public List<HmTodoItemsVo> queryList(HmTodoItemsBo bo)
    {
        LambdaQueryWrapper<HmTodoItems> lqw = buildQueryWrapper(bo);
        return baseMapper.selectVoList(lqw);
    }

    private LambdaQueryWrapper<HmTodoItems> buildQueryWrapper(HmTodoItemsBo bo)
    {
        if (bo.getTodoCompletionTime() != null)
        {
            LocalDateTime localDateTime = DateUtil.toLocalDateTime(bo.getTodoCompletionTime());
            String format = localDateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
            bo.setTodoCompletionTimeStr(format);
        }
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<HmTodoItems> lqw = Wrappers.lambdaQuery();
        // 若当前登录人的角色包含市场总监,则只查询代办类型为回访的数据,即todoType = 0
        if (LoginHelper.isDeptManager())
        {
            lqw.eq(HmTodoItems::getTodoType, ToDoTypeEnum.RETURN_VISIT.getCode());
        }
        else
        {
            lqw.eq(StringUtils.isNotBlank(bo.getTodoType()), HmTodoItems::getTodoType, bo.getTodoType());
        }

        lqw.like(StringUtils.isNotBlank(bo.getTodoDesc()), HmTodoItems::getTodoDesc, bo.getTodoDesc());
        lqw.eq(bo.getTodoStockNum() != null, HmTodoItems::getTodoStockNum, bo.getTodoStockNum());
        lqw.eq(bo.getTodoStockDept() != null, HmTodoItems::getTodoStockDept, bo.getTodoStockDept());
        lqw.eq(bo.getTodoPersonId() != null, HmTodoItems::getTodoPersonId, bo.getTodoPersonId());
        lqw.eq(bo.getSubmitterId() != null, HmTodoItems::getSubmitterId, bo.getSubmitterId());
        lqw.eq(bo.getApproverId() != null, HmTodoItems::getApproverId, bo.getApproverId());
        lqw.like(StringUtils.isNotBlank(bo.getTodoPersonName()), HmTodoItems::getTodoPersonName, bo.getTodoPersonName());
        lqw.eq(StringUtils.isNotBlank(bo.getTodoResult()), HmTodoItems::getTodoResult, bo.getTodoResult());
        lqw.between(params.containsKey("beginTime") && params.containsKey("endTime"), HmTodoItems::getTodoCompletionTime, params.get("beginTime"), params.get("endTime"));
        lqw.like(bo.getTodoCompletionTime() != null, HmTodoItems::getTodoCompletionTime, bo.getTodoCompletionTimeStr());
        lqw.eq(StringUtils.isNotBlank(bo.getStatus()), HmTodoItems::getStatus, bo.getStatus());
        lqw.eq(bo.getFollowCustomerId() != null, HmTodoItems::getFollowCustomerId, bo.getFollowCustomerId());
        lqw.eq(bo.getTodoWarehouseReceipt() != null, HmTodoItems::getTodoWarehouseReceipt, bo.getTodoWarehouseReceipt());
        lqw.eq(bo.getTodoOutboundOrder() != null, HmTodoItems::getTodoOutboundOrder, bo.getTodoOutboundOrder());
        lqw.orderByDesc(HmTodoItems::getCreateTime);
        return lqw;
    }

    /**
     * 新增代办事项
     *
     * @param bo 代办事项
     *
     * @return 是否新增成功
     */
    @Override
    public Boolean insertByBo(HmTodoItemsBo bo)
    {
        HmTodoItems add = MapstructUtils.convert(bo, HmTodoItems.class);
        if (add != null)
        {
            add.setTodoFile(JsonUtils.toJsonString(bo.getTodoFiles()));

            // 自动设置提交人信息（如果未设置）
            if (add.getSubmitterId() == null) {
                add.setSubmitterId(LoginHelper.getUserId());
                add.setSubmitterName(LoginHelper.getUsername());
            }

            // 自动设置审核人信息（如果未设置）
            if (add.getApproverId() == null && add.getTodoPersonId() != null) {
                add.setApproverId(add.getTodoPersonId());
                add.setApproverName(add.getTodoPersonName());
            }
        }
        if (TodoFollowIpTypeEnum.STORE_MEETING.getCode().equals(add.getFollowType()) || TodoFollowIpTypeEnum.COMPANY_CONFERENCE.getCode()
            .equals(add.getFollowType()))
        {
            HmCustomerVo hmCustomerVo = customerService.selectVoById(bo.getFollowCustomerId());
            add.setTodoDesc("客户:" + hmCustomerVo.getCustomerName() + ",参与" + TodoFollowIpTypeEnum.getByCode(Integer.parseInt(add.getFollowType()))
                .getDescription());
        }

        boolean flag = baseMapper.insert(add) > 0;
        if (flag)
        {
            bo.setTodoId(add.getTodoId());
        }
        return flag;
    }

    /**
     * 更新代办事项
     *
     * @param bo 代办事项
     *
     * @return 是否修改成功
     */
    @Override
    public Boolean updateByBo(HmTodoItemsBo bo)
    {
        try
        {
            HmTodoItems update = MapstructUtils.convert(bo, HmTodoItems.class);
            if (update != null && bo.getTodoFiles()!= null)
            {
                update.setTodoFile(String.join(",", bo.getTodoFiles()));
            }
            return baseMapper.updateById(update) > 0;
        }
        catch (Exception e)
        {
            throw new RuntimeException(e);
        }

    }

    /**
     * 处理代办事项
     *
     * @param bo 代办事项
     *
     * @return 是否修改成功
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean processingAgent(HmTodoItemsBo bo)
    {
        try
        {
            HmTodoItems update = MapstructUtils.convert(bo, HmTodoItems.class);
            // 查询当前待办状态
            HmTodoItemsVo hmTodoItemsVo = null;
            if (update != null)
            {
                hmTodoItemsVo = queryById(update.getTodoId());
            }

            // 权限检查：只有审核人或超级管理员可以审核
            Long currentUserId = LoginHelper.getUserId();
            boolean isAdmin = LoginHelper.isAdmin();
            if (hmTodoItemsVo != null && hmTodoItemsVo.getApproverId() != null) {
                // 如果既不是审核人也不是超级管理员，则无权审核
                if (!currentUserId.equals(hmTodoItemsVo.getApproverId()) && !isAdmin) {
                    throw new ServiceException("您无权审核此待办事项，只有审核人或超级管理员可以审核");
                }
            }

            // 驳回逻辑
            if (TodoItemStatus.REJECTED.getCode().equals(bo.getStatus()))
            {
                HmIssueReceiptRecordsVo hmIssueReceiptRecordsVo;

                if (ToDoTypeEnum.EMPLOYEE_BENEFITS.getCode().equals(bo.getTodoType()) || ToDoTypeEnum.CUSTOMER_GIFTS.getCode()
                    .equals(bo.getTodoType()) || ToDoTypeEnum.FRINGE_MARKET.getCode().equals(bo.getTodoType()))
                {
                    // 员工福利或者客户赠品或者外围市场驳回
                    hmIssueReceiptRecordsVo = issueReceiptRecordsMapper.selectVoById(bo.getTodoOutboundOrder());

                }
                else
                {
                    // 入库驳回
                    if (bo.getTodoWarehouseReceipt() != null)
                    {
                        // 1. 自增入库单驳回
                        hmIssueReceiptRecordsVo = issueReceiptRecordsMapper.selectVoById(bo.getTodoWarehouseReceipt());
                    }
                    else
                    {
                        // 2. 跨店入库驳回
                        hmIssueReceiptRecordsVo = issueReceiptRecordsMapper.selectVoById(bo.getTodoOutboundOrder());
                    }

                }
                if (ObjectUtil.isNotEmpty(hmIssueReceiptRecordsVo))
                {
                    // 修改当前出入库信息为驳回
                    HmIssueReceiptRecords updateRecords = new HmIssueReceiptRecords();
                    updateRecords.setStatus("BH");
                    updateRecords.setRecordId(hmIssueReceiptRecordsVo.getRecordId());
                    issueReceiptRecordsMapper.updateById(updateRecords);
                }
                else
                {
                    throw new ServiceException("驳回失败,请联系管理员查看原因!");
                }
            }
            else
            {
                if (hmTodoItemsVo != null && TodoItemStatus.FINISHED.getCode().equals(hmTodoItemsVo.getStatus()))
                {
                    throw new ServiceException("该待办已处理,请勿重复操作!");
                }
                if (update != null)
                {
                    if (bo.getTodoFiles() != null)
                    {
                        update.setTodoFile(String.join(",", bo.getTodoFiles()));
                    }

                }
                // 合并条件判断 非驳回的
                if (Boolean.FALSE.equals(bo.getIsAgain()))
                {
                    validEntityBeforeSave(update);

                    // 阈值提醒类待办批量办结逻辑
                    if (shouldBatchComplete(update))
                    {
                        LambdaUpdateWrapper<HmTodoItems> updateWrapper = Wrappers.lambdaUpdate();
                        updateWrapper.eq(HmTodoItems::getOrderId, update.getOrderId()).set(HmTodoItems::getStatus, TodoItemStatus.FINISHED.getCode());
                        baseMapper.update(null, updateWrapper);
                    }
                }

            }
            return baseMapper.updateById(update) > 0;
        }
        catch (Exception e)
        {
            throw new RuntimeException(e);
        }

    }

    private boolean shouldBatchComplete(HmTodoItems update)
    {
        return ToDoTypeEnum.THRESHOLD.getCode().equals(update.getTodoType()) && TodoItemStatus.FINISHED.getCode()
            .equals(update.getStatus()) && update.getOrderId() != null;
    }

    /**
     * 保存前的数据校验
     */
    private void validEntityBeforeSave(HmTodoItems entity)
    {
        // 处理回款调整待办
        if (ToDoTypeEnum.PAYMENT_ADJUSTMENT.getCode().equals(entity.getTodoType()))
        {
            // 回款调整待办处理逻辑
//            hmPaymentAdjustmentService.approveAdjustment()
            // 注意：这里只是更新待办状态，实际的审核逻辑在 HmPaymentAdjustmentServiceImpl 中
            // 前端应该直接调用 /hm/paymentAdjustment/approve 或 /reject 接口
            // 这里不需要额外处理，因为审核接口已经包含了完整的业务逻辑
            return;
        }

        // 检查当前操作是否为入库办理操作,若为入库办理操作则需要同步在入库记录中生成一条入库单记录
        if (ToDoTypeEnum.RECEIPT.getCode().equals(entity.getTodoType()) || ToDoTypeEnum.AUTO_RECEIPT.getCode().equals(entity.getTodoType())) // 跨店入库 or 自增入库
        {
            boolean isSelfAddedReceipt = entity.getTodoWarehouseReceipt() != null && ToDoTypeEnum.AUTO_RECEIPT.getCode().equals(entity.getTodoType()); // 自增入库
            // 判断当前是否已经有入库单ID,若有则为自入库操作
            if (isSelfAddedReceipt)
            {
                // 同步更新入库状态为通过
                HmIssueReceiptRecordsVo outBoundOrder = issueReceiptRecordsMapper.selectVoById(entity.getTodoWarehouseReceipt());
                if (outBoundOrder != null)
                {
                    outBoundOrder.setStatus("TG");
                    HmIssueReceiptRecords updateOutBoundOrder = MapstructUtils.convert(outBoundOrder, HmIssueReceiptRecords.class);
                    issueReceiptRecordsMapper.updateById(updateOutBoundOrder);
                }
            }
            else
            {
                // 跨店入库
                HmIssueReceiptRecords hmIssueReceiptRecordsBo = new HmIssueReceiptRecords();
                hmIssueReceiptRecordsBo.setRecordProductId(entity.getTodoStockGoodsId());
                hmIssueReceiptRecordsBo.setRecordNum(entity.getTodoStockNum());
                hmIssueReceiptRecordsBo.setRecordStartLocation(entity.getTodoOutboundDept().toString());
                hmIssueReceiptRecordsBo.setRecordEndLocation(entity.getTodoStockDept().toString());
                hmIssueReceiptRecordsBo.setRecordType(INBOUND.getCode()); // 跨店入库
                hmIssueReceiptRecordsBo.setStatus("TG"); // 通过

                HmIssueReceiptRecordsVo outBoundOrder = issueReceiptRecordsMapper.selectVoById(entity.getTodoOutboundOrder());
                if (outBoundOrder != null)
                {
                    // 保存新的出入库单记录
                    hmIssueReceiptRecordsBo.setRecordProductType(outBoundOrder.getRecordProductType());
                    issueReceiptRecordsMapper.insert(hmIssueReceiptRecordsBo);

                    // 更新原出库单记录
                    outBoundOrder.setStatus("TG");
                    HmIssueReceiptRecords updateOutBoundOrder = MapstructUtils.convert(outBoundOrder, HmIssueReceiptRecords.class);
                    issueReceiptRecordsMapper.updateById(updateOutBoundOrder);
                }
                entity.setTodoWarehouseReceipt(hmIssueReceiptRecordsBo.getRecordId()); // 入库单ID

                // 修改出库库存数据
                // 查询当前出库仓库的出库商品库存数量
                // TODO 目前查询的是当前出库仓库
                HmStockVo hmStockOutVo = stockMapper.selectVoOne(Wrappers.lambdaQuery(HmStock.class)
                    .eq(HmStock::getStockProductId, entity.getTodoStockGoodsId()).eq(HmStock::getProductDept, entity.getTodoOutboundDept()));
                if (ObjectUtil.isEmpty(hmStockOutVo) || hmStockOutVo.getStockNum().compareTo(entity.getTodoStockNum()) < 0)
                {
                    throw new ServiceException("出库仓库库存不足,无法完成入库操作");
                }
                HmStock hmStockBo = new HmStock();
                // 库存数量
                hmStockBo.setStockNum(hmStockOutVo.getStockNum().subtract(entity.getTodoStockNum()));
                // 更新的库存id
                hmStockBo.setStockId(hmStockOutVo.getStockId());
                stockMapper.updateById(hmStockBo);

                // 出库变更记录
                HmStockChangeBo hmStockChangeBo = new HmStockChangeBo();
                hmStockChangeBo.setStockId(hmStockBo.getStockId()); // 库存id
                hmStockChangeBo.setChangeType(StockChangeTypeEnum.OUTBOUND.getCode()); // 出库
                hmStockChangeBo.setChangeInfo(StockChangeTypeEnum.OUTBOUND.getDescription()); // 变更详情
                hmStockChangeBo.setChangeNum(entity.getTodoStockNum());// 变更数量
                hmStockChangeBo.setChangeTime(new Date()); // 变更时间
                hmStockChangeBo.setProductId(String.valueOf(entity.getTodoStockGoodsId())); // 变更商品id
                hmStockChangeBo.setRecordStartLocation(entity.getTodoOutboundDept().toString()); // 出库地
                hmStockChangeBo.setRecordEndLocation(entity.getTodoStockDept().toString()); // 入库地
                hmStockChangeBo.setProof(entity.getTodoFile());
                String outDeptName = deptService.selectDeptNameByIds(String.valueOf(entity.getTodoOutboundDept()));
                String InDeptName = deptService.selectDeptNameByIds(String.valueOf(entity.getTodoStockDept()));
                hmStockChangeBo.setRemark(String.format("出库仓库:%s,入库仓库:%s", outDeptName, InDeptName));
                hmStockChangeService.insertByBo(hmStockChangeBo);

            }
            // 同步修改入库库存数据
            // 1. 查询入库仓库的入库商品是否有库存
            HmStockVo hmStockVo = stockMapper.selectVoOne(Wrappers.lambdaQuery(HmStock.class).eq(HmStock::getProductDept, entity.getTodoStockDept())
                .eq(HmStock::getStockProductId, entity.getTodoStockGoodsId()));
            if (hmStockVo != null)
            {
                // 2. 若有库存则修改库存数量
                hmStockVo.setStockNum(hmStockVo.getStockNum().add(entity.getTodoStockNum()));
                stockMapper.updateById(MapstructUtils.convert(hmStockVo, HmStock.class));

                // 变更记录
                HmStockChangeBo hmStockChangeBo = new HmStockChangeBo();
                hmStockChangeBo.setStockId(hmStockVo.getStockId()); // 库存id
                if (isSelfAddedReceipt)
                {
                    // 自增入库
                    hmStockChangeBo.setChangeType(StockChangeTypeEnum.SELF_ADDED_RECEIPT.getCode()); // 自增入库
                    hmStockChangeBo.setChangeInfo(StockChangeTypeEnum.SELF_ADDED_RECEIPT.getDescription()); // 变更详情
                }
                else
                {
                    // 跨店入库
                    hmStockChangeBo.setChangeType(StockChangeTypeEnum.INBOUND.getCode()); // 跨店入库
                    hmStockChangeBo.setChangeInfo(StockChangeTypeEnum.INBOUND.getDescription()); // 变更详情
                }
                hmStockChangeBo.setRecordStartLocation(entity.getTodoOutboundDept().toString()); // 出库地
                hmStockChangeBo.setRecordEndLocation(entity.getTodoStockDept().toString()); // 入库地
                hmStockChangeBo.setChangeNum(entity.getTodoStockNum());// 变更数量
                hmStockChangeBo.setChangeTime(new Date()); // 变更时间
                hmStockChangeBo.setProductId(String.valueOf(entity.getTodoStockGoodsId())); // 变更商品id
                hmStockChangeBo.setProof(entity.getTodoFile());
                hmStockChangeService.insertByBo(hmStockChangeBo);

            }
            else
            {
                // 3. 若无库存则新增一条库存记录
                HmStock hmStock = new HmStock();
                hmStock.setProductDept(entity.getTodoStockDept());
                hmStock.setStockProductId(entity.getTodoStockGoodsId());
                hmStock.setStockNum(entity.getTodoStockNum());
                stockMapper.insert(hmStock);

                // 入库变更记录
                HmStockChangeBo hmStockChangeBo = new HmStockChangeBo();
                hmStockChangeBo.setStockId(hmStock.getStockId()); // 库存id
                if (isSelfAddedReceipt)
                {
                    // 自增入库
                    hmStockChangeBo.setChangeType(StockChangeTypeEnum.SELF_ADDED_RECEIPT.getCode()); // 自增入库
                    hmStockChangeBo.setChangeInfo(StockChangeTypeEnum.SELF_ADDED_RECEIPT.getDescription()); // 变更详情
                }
                else
                {
                    // 跨店入库
                    hmStockChangeBo.setChangeType(StockChangeTypeEnum.INBOUND.getCode()); // 跨店入库
                    hmStockChangeBo.setChangeInfo(StockChangeTypeEnum.INBOUND.getDescription()); // 变更详情
                }
                hmStockChangeBo.setChangeNum(entity.getTodoStockNum());// 变更数量
                hmStockChangeBo.setChangeTime(new Date()); // 变更时间
                hmStockChangeBo.setProductId(String.valueOf(entity.getTodoStockGoodsId())); // 变更商品id
                hmStockChangeBo.setRecordStartLocation(entity.getTodoOutboundDept().toString()); // 出库地
                hmStockChangeBo.setRecordEndLocation(entity.getTodoStockDept().toString()); // 入库地
                hmStockChangeBo.setProof(entity.getTodoFile());
                hmStockChangeService.insertByBo(hmStockChangeBo);
            }

            // 将事件状态设置为完成
            entity.setStatus("1");
        }
        else if (ToDoTypeEnum.EMPLOYEE_BENEFITS.getCode().equals(entity.getTodoType()) || ToDoTypeEnum.CUSTOMER_GIFTS.getCode().equals(entity.getTodoType()))
        {
            // 员工福利或者客户赠品
            HmIssueReceiptRecordsVo outBoundOrder = issueReceiptRecordsMapper.selectVoById(entity.getTodoOutboundOrder());
            if (outBoundOrder != null)
            {
                // 更新原出库单记录
                outBoundOrder.setStatus("TG");
                HmIssueReceiptRecords updateOutBoundOrder = MapstructUtils.convert(outBoundOrder, HmIssueReceiptRecords.class);
                issueReceiptRecordsMapper.updateById(updateOutBoundOrder);

                // 修改出库库存数据
                // 查询当前出库仓库的出库商品库存数量 //TODO 目前查询的是当前出库仓库
                HmStockVo hmStockOutVo = stockMapper.selectVoOne(Wrappers.lambdaQuery(HmStock.class)
                    .eq(HmStock::getStockProductId, entity.getTodoStockGoodsId()).eq(HmStock::getProductDept, entity.getTodoOutboundDept()));
                if (ObjectUtil.isEmpty(hmStockOutVo) || hmStockOutVo.getStockNum().compareTo(entity.getTodoStockNum()) < 0)
                {
                    throw new ServiceException("出库仓库库存不足,无法完成入库操作");
                }
                HmStock hmStockBo = new HmStock();
                // 库存数量
                hmStockBo.setStockNum(hmStockOutVo.getStockNum().subtract(entity.getTodoStockNum()));
                // 更新的库存id
                hmStockBo.setStockId(hmStockOutVo.getStockId());
                stockMapper.updateById(hmStockBo);

                // 出库变更记录
                HmStockChangeBo hmStockChangeBo = new HmStockChangeBo();
                hmStockChangeBo.setStockId(hmStockBo.getStockId()); // 库存id
                String userName = userService.selectNicknameByIds(entity.getTodoPersonId().toString());
                if(entity.getTodoPersonName() == null){
                    entity.setTodoPersonName(userName);
                }
                HmIssueReceiptRecordsVo hmIssueReceiptRecordsVo = issueReceiptRecordsMapper.selectVoById(entity.getTodoOutboundOrder());

                if (entity.getTodoType().equals(ReceiptIssueRecordTypeEnum.EMPLOYEE_BENEFITS.getCode()))
                {

                    hmStockChangeBo.setChangeType(StockChangeTypeEnum.EMPLOYEE_BENEFITS.getCode());
                    hmStockChangeBo.setChangeInfo(StockChangeTypeEnum.EMPLOYEE_BENEFITS.getDescription());
                    hmStockChangeBo.setRemark(String.format("[%s出库],审核员:%s", StockChangeTypeEnum.EMPLOYEE_BENEFITS.getDescription(), entity.getTodoPersonName()));
                }
                else
                {
                    hmStockChangeBo.setChangeType(StockChangeTypeEnum.CUSTOMER_GIFTS.getCode());
                    hmStockChangeBo.setChangeInfo(StockChangeTypeEnum.CUSTOMER_GIFTS.getDescription());
                    // 列举所有赠送的客户姓名
                    List<String> customerIds = Arrays.asList(Optional.of(hmIssueReceiptRecordsVo).orElse(new HmIssueReceiptRecordsVo()).getUserOrCustomerIds()
                        .split(","));
                    List<HmCustomerVo> hmCustomerVos = customerService.selectVoByIds(customerIds);
                    String customerName = "";
                    if (ObjectUtil.isNotEmpty(hmCustomerVos)){
                        customerName = hmCustomerVos.stream().map(HmCustomerVo::getCustomerName).collect(Collectors.joining(","));
                    }
                    if(entity.getTodoDesc() != null){
                        String staffName = "";
                        String user = entity.getTodoDesc().split(",")[0];
                        if(user != null){
                            staffName = user.replaceAll("员工:", "");
                        }
                        hmStockChangeBo.setRemark(String.format("[%s出库],员工:%s,客户:%s", StockChangeTypeEnum.CUSTOMER_GIFTS.getDescription(),staffName,customerName));
                    }
                }
                hmStockChangeBo.setChangeNum(entity.getTodoStockNum());// 变更数量
                hmStockChangeBo.setChangeTime(new Date()); // 变更时间
                hmStockChangeBo.setProductId(String.valueOf(entity.getTodoStockGoodsId())); // 变更商品id
                hmStockChangeBo.setRecordStartLocation(entity.getTodoOutboundDept().toString()); // 出库地
                hmStockChangeBo.setProof(entity.getTodoFile());

                hmStockChangeService.insertByBo(hmStockChangeBo);
            }
        }
        else if (ToDoTypeEnum.SALE_ORDER_REFUND.getCode().equals(entity.getTodoType()))
        {
            // 退款退货提醒
            // 1. 拿取退货订单id查询对应的退货退款明细表
            HmSaleOrderRefundBo hmSaleOrderRefundBo = new HmSaleOrderRefundBo();
            if(entity.getReturnOrderId() != null){
                hmSaleOrderRefundBo.setRefundId(entity.getReturnOrderId().toString());
                List<HmSaleOrderRefundVo> hmSaleOrderRefundVos = hmSaleOrderRefundService.queryList(hmSaleOrderRefundBo);
                if(ObjectUtil.isNotEmpty(hmSaleOrderRefundVos)){
                    hmSaleOrderRefundVos.forEach(vo->{
                        // 只有当 actualReturnToStockNum > 0 时才回填库存
                        if (Optional.ofNullable(vo.getActualReturnToStockNum()).orElse(BigDecimal.ZERO).compareTo(BigDecimal.ZERO) > 0) {
                            // 3. 查询库存表中是否有该商品的库存
                            HmStockVo hmStockVo = stockMapper.selectVoOne(Wrappers.lambdaQuery(HmStock.class)
                                .eq(HmStock::getStockProductId, vo.getSaleProductId()).eq(HmStock::getProductDept, entity.getTodoStockDept()));
                            // 如果库存记录不存在，则新增一条
                            if (hmStockVo == null) {
                                HmStock newStock = new HmStock();
                                newStock.setProductDept(entity.getTodoStockDept());
                                newStock.setStockProductId(Long.valueOf(vo.getSaleProductId()));
                                newStock.setStockNum(vo.getActualReturnToStockNum());
                                stockMapper.insert(newStock);
                                hmStockVo = MapstructUtils.convert(newStock, HmStockVo.class); // 转换为VO以便后续使用
                            } else {
                                // 2. 若有库存则修改库存数量
                                hmStockVo.setStockNum(hmStockVo.getStockNum().add(vo.getActualReturnToStockNum()));
                                stockMapper.updateById(MapstructUtils.convert(hmStockVo, HmStock.class));
                            }

                            // 出库变更记录
                            HmStockChangeBo hmStockChangeBo = new HmStockChangeBo();
                            hmStockChangeBo.setStockId(hmStockVo.getStockId()); // 库存id
                            hmStockChangeBo.setChangeType(StockChangeTypeEnum.RETURN_RECEIPT.getCode());
                            hmStockChangeBo.setChangeInfo(StockChangeTypeEnum.RETURN_RECEIPT.getDescription());
                            // 处理目的地
                            hmStockChangeBo.setRemark(String.format("销售订单[%s],%s",vo.getSaleId(),StockChangeTypeEnum.RETURN_RECEIPT.getDescription()));
                            hmStockChangeBo.setChangeNum(vo.getActualReturnToStockNum());// 变更数量
                            hmStockChangeBo.setChangeTime(new Date()); // 变更时间
                            hmStockChangeBo.setProductId(String.valueOf(vo.getSaleProductId())); // 变更商品id
                            hmStockChangeBo.setProof(entity.getTodoFile());
                            hmStockChangeService.insertByBo(hmStockChangeBo);
                        }
                    });
                }
            }else{
                throw new RuntimeException("未找到对应的退款订单,请联系管理员查看");
            }


        }
        else if (ToDoTypeEnum.FRINGE_MARKET.getCode().equals(entity.getTodoType()))
        {
            // 外围市场提醒
            HmIssueReceiptRecordsVo outBoundOrder = issueReceiptRecordsMapper.selectVoById(entity.getTodoOutboundOrder());
            if (outBoundOrder != null)
            {
                // 更新原出库单记录
                outBoundOrder.setStatus("TG");
                HmIssueReceiptRecords updateOutBoundOrder = MapstructUtils.convert(outBoundOrder, HmIssueReceiptRecords.class);
                issueReceiptRecordsMapper.updateById(updateOutBoundOrder);

                // 修改出库库存数据
                // 查询当前出库仓库的出库商品库存数量 //TODO 目前查询的是当前出库仓库
                HmStockVo hmStockOutVo = stockMapper.selectVoOne(Wrappers.lambdaQuery(HmStock.class)
                    .eq(HmStock::getStockProductId, entity.getTodoStockGoodsId()).eq(HmStock::getProductDept, entity.getTodoOutboundDept()));
                if (ObjectUtil.isEmpty(hmStockOutVo) || hmStockOutVo.getStockNum().compareTo(entity.getTodoStockNum()) < 0)
                {
                    throw new ServiceException("出库仓库库存不足,无法完成入库操作");
                }
                HmStock hmStockBo = new HmStock();
                // 库存数量
                hmStockBo.setStockNum(hmStockOutVo.getStockNum().subtract(entity.getTodoStockNum()));
                // 更新的库存id
                hmStockBo.setStockId(hmStockOutVo.getStockId());
                stockMapper.updateById(hmStockBo);

                // 出库变更记录
                HmStockChangeBo hmStockChangeBo = new HmStockChangeBo();
                hmStockChangeBo.setStockId(hmStockBo.getStockId()); // 库存id
                hmStockChangeBo.setChangeType(StockChangeTypeEnum.FRINGE_MARKET.getCode());
                hmStockChangeBo.setChangeInfo(StockChangeTypeEnum.FRINGE_MARKET.getDescription());
                // 处理目的地
                String destination = entity.getTodoDesc().substring(StringUtils.indexOf(entity.getTodoDesc(),"目"));
                hmStockChangeBo.setRemark(String.format("[%s],%s", StockChangeTypeEnum.FRINGE_MARKET.getDescription(),destination));
                hmStockChangeBo.setChangeNum(entity.getTodoStockNum());// 变更数量
                hmStockChangeBo.setChangeTime(new Date()); // 变更时间
                hmStockChangeBo.setProductId(String.valueOf(entity.getTodoStockGoodsId())); // 变更商品id
                hmStockChangeBo.setRecordStartLocation(entity.getTodoOutboundDept().toString()); // 出库地
                hmStockChangeBo.setProof(entity.getTodoFile());
                hmStockChangeService.insertByBo(hmStockChangeBo);
            }
        }

    }

    /**
     * 校验并批量删除代办事项信息
     *
     * @param ids     待删除的主键集合
     * @param isValid 是否进行有效性校验
     *
     * @return 是否删除成功
     */
    @Override
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid)
    {
        if (isValid)
        {
            //TODO 做一些业务上的校验,判断是否需要校验
        }
        return baseMapper.deleteByIds(ids) > 0;
    }

    @Override
    public void updateTodoItems(Long oldStaffId, Long effectiveNewStaffId, String effectiveNewStaffName, String operatorUsername, Date now)
    {
        baseMapper.updateTodoItems(oldStaffId, effectiveNewStaffId,effectiveNewStaffName,operatorUsername, now);
    }

    @Override
    public List<HmTodoItems> selectPendingTodosByStaffId(Long staffId)
    {
        return baseMapper.selectPendingTodosByStaffId(staffId);
    }

    /**
     * 根据客户ID列表批量更新待办事项的归属。
     * @param customerIds 客户ID列表
     * @param newStaffId 新员工ID
     * @param newStaffName 新员工姓名
     * @param operatorUsername 操作人用户名
     * @param now 当前时间
     */
    @Override
    public void updateTodoItemsByCustomerIds(List<Long> customerIds, Long newStaffId, String newStaffName, String operatorUsername, Date now) {
        baseMapper.updateTodoItemsByCustomerIds(customerIds, newStaffId, newStaffName, operatorUsername, now);
    }

    /**
     * 查询指定客户ID列表下所有未完成的待办事项。
     * @param customerIds 客户ID列表
     * @return 待办事项列表
     */
    @Override
    public List<HmTodoItems> selectPendingTodosByCustomerIds(List<Long> customerIds) {
        return baseMapper.selectPendingTodosByCustomerIds(customerIds);
    }
}
